//----------------------------------------------------------------------------------------------------
//
// Copyright (c) 2008 Cypress Semiconductor Corporation. All rights reserved.
//
// This file contains Source Code. You may not use this file except in compliance
// with the Cypress Semiconductor Corporation IP Library License and Usage Agreement.
//
// Please obtain a copy of the Agreement at
//
// http://www.cypress.com/IP_Library_License_Agreement.pdf
//
// and read it before using this file. 
//
// The Source Code and all software distributed under the Agreement are distributed on an 'AS IS' basis,
// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS, IMPLIED OR STATUTORY, REGARDING THE SUFFICIENCY, 
// ACCURACY OR COMPLETENESS OF THE INFORMATION AND CYPRESS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
// AND NON-INFRINGEMENT. Cypress Semiconductor Corporation reserves the right to make changes to the 
// Source Code and any software distributed under the Agreement without further notice.
//
// Please see the License and Usage Agreement for the specific language governing rights and 
// limitations under the Agreement.
//
//----------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------
//  FILENAME:   main.c
//
//  DESCRIPTION: 
//
//
//----------------------------------------------------------------------------------------------------
#include "global.h"

/* State machine function pointer declaration */
void (*CallStateMachine[8])(void) = { &InitState,			/* Initialize User Modules, Power Core & constants */
									  &StartState, 			/* Check all error conditions, determine operating state & ensure safe start */
									  &MPPTState,  			/* Test for the MPPT point, park the panel at this point and track this point */
									  &ConstCurrentState,   /* For fully depleted batteries, charge the battery at Constant Current */
									  &TrickleChargeCVState,  /* For a almost charged battery, trickle charge it till it reaches a full charge */
									  &LoadEnableState, 	/* When a dusk condition is detected enable the load */
									  &StatusUpdateState, 	/* Save the system parameters in EEPROM */
									  &FaultState }; 		/* Give the fault indication & Wait for fault condition recovery */

void main()
{  
  unsigned int wIndex; 
  bCurState = Init;
  
  /* Initialize the User Modules */  
  InitState();

  #ifdef TC1
  Test_IOs();  
  #endif
  
  #ifdef TEST_CORE
  Test_Core();
  #endif
  
  #ifdef TEST_LED 
  Test_LED();  
  #endif
  
  #ifdef TEST_BATTERY 
  Test_Battery();  
  #endif
  
  while(1)
  {
    /* Call the current state function */
	CallStateMachine[bCurState]();        
  }		  												  
}

//****************************************************************************
//****************************************************************************
// FUNCTION NAME: InitConstants
//
// DESCRIPTION:
//   Initialise and start all user modules
//
//----------------------------------------------------------------------------
//
// ARGUMENTS: none
//
// RETURNS:   none
//****************************************************************************
void InitConstants()
{
  SConstSCC.cModTempMax = 70;
  SConstSCC.cBatTempMax = 50;
  SConstSCC.bIMaxLow = (unsigned char)DAC_I_VALLEY_CC;
  SConstSCC.bIMaxHigh = (unsigned char)DAC_I_PEAK_CC;
  SConstSCC.wVOCth = (unsigned int)VOC_TH; 	
  SConstSCC.wVdiff = (unsigned int)VDIFF;
  SConstSCC.wVdiff_low = (unsigned int)VDIFF_LOW;
  SConstSCC.wVbat_min_high = (unsigned int)VBAT_ON;
  SConstSCC.wVbat_th = (unsigned int)MPPT_TH;
  SConstSCC.wVbat_th_low = (unsigned int)MPPT_TH_LOW;
  SConstSCC.wVbat_TC = (unsigned int)TC_LOW_TH;
  SConstSCC.wVbat_max = (unsigned int)TC_HIGH_TH;
  SConstSCC.wVbatOV = (unsigned int)BATOV_TH;
  SConstSCC.wVCC_th = (unsigned int)CC_TH;
  SConstSCC.wThyst= 100;   
  
  MeasureBatteryVoltage(); 
  if(SInputSCC.wCalcVbat <= SConstSCC.wVbat_th_low)
  {
    bTCFlag = 1;
  }	
}  

//****************************************************************************
//****************************************************************************
// FUNCTION NAME: InitState
//
// DESCRIPTION:
//   Initialise and start all user modules
//
//----------------------------------------------------------------------------
//
// ARGUMENTS: none
//
// RETURNS:   none
//****************************************************************************
void InitState()
 {   
  BYTE bTemp[2];  
  
  /* Since on reset the IO is at logic 0 and the Load relay is active low enable
  disable the load on start-up */
  Load_Disable;
  
  // Start PGA,used as the ADC Buffer.Various Analog Inputs can be multiplexed to a PGA.
  Buffer_Start(Buffer_LOWPOWER);
  
  // Start ADC - used for measuring battery voltage, solar panel voltage, thermistor voltage
  DelSigADC_Start( DelSigADC_LOWPOWER );  
  DelSigADC_StartAD(); 
  
  // Enable Timer Interrupt, for setting timeout of various events
  Timer24_EnableInt();  
    
  Timer24_WritePeriod(TOUT);
  
  /* ensure interrupt is disabled */  
  LEDClk_DisableInt();  
  /* start the LEDClk PWM, this is used to provide clock to the LED1 & LED2 PWM modules */  
  LEDClk_Start(); 
  
  /* ensure interrupt is disabled */  
  LED1_DisableInt();  
  /* start the LED1 PWM, this is used to give provide diffrent blinking rates for LED1 */  
  //LED1_Start(); 
	
  /* Ensure interrupt is disabled */  
  LED2_DisableInt();  

  /* Start the in-built temperature sensor */
  FlashTemp_Start(); 
  
  /* Initialize user modules used for communication with PC */
  InitCommUM();
        
  /* Enable Global Interrupt */
  M8C_EnableGInt;  
  
  /* Start Timer */
  Timer24_Start();  
  
  /* Start E2PROM */
  E2PROM_Start();
    
  /* Read the E2PROM data pointer into a RAM buffer */  
  E2PROM_E2Read(EEPROM_POINTER, wEEPROMPtr.abDataIndex, 2 );  
  
  /* At reset the entire flash has 0x30, set the wEEPROMPtr.wDataIndex to 0 to initialise the pointer */
  if(wEEPROMPtr.wDataIndex == 0x3030)
    wEEPROMPtr.wDataIndex = 0;

  /* Initialize the constants */
  InitConstants();
    
  /* Initialize the power core User Modules */
  InitPowerCore();  
  
#ifndef AUTOMATIC_DUSK_TO_DAWN
  MeasureBatteryVoltage();
  /* Test if the battery voltage is sufficient to drive the load */
  if(SInputSCC.wCalcVbat > SConstSCC.wVbat_min_high) 
  {
    /* Enable the load */
    Load_Enable;
  }	    
#endif

  /* Store the previous state to check state transistion */
  /* This data will also be stored in E2PROM as a part of User data */
  bPrevState = bCurState;  
  /* After Intialisation is complete, change the current state to Start */
  bCurState = Start;
  
  StablisationDelay();
}

//****************************************************************************
//****************************************************************************
// FUNCTION NAME: InitPowerCore
//
// DESCRIPTION:
//   Initialise Power PSoC user modules
//
//----------------------------------------------------------------------------
//
// ARGUMENTS: none
//
// RETURNS:   none
//****************************************************************************
void InitPowerCore()
{ 
  /* Start UM which are used to indicate Battery Under Voltage disconnect by switching on the LED */
  DualDAC8HW_BAT_LOW_Start();
  CMPHW_BAT_LOW_Start();  
  DualDAC8HW_BAT_LOW_Write1(VBAT_ON_REF);	   	
  DualDAC8HW_BAT_LOW_Write2(VBAT_ON_REF);	  

  /* Start UM which are used to measure input current */
  DualDAC8HW_IN_Start();
  CMPHW_IN_Start();
  
  /* Start UM which are used for Indicating battery low  */
  DualDAC8HW_BAT_LOW_Start();
  CMPHW_BAT_LOW_Start();

  //DualDAC8HW_BAT_LOW_Write1(bTemp);	  
  //DualDAC8HW_BAT_LOW_Write2(bTemp);
		
  /* Set High reference */                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
  HYSTCTRL_BAT_SetRefHigh(bHigh);
  /* Set Low reference */
  HYSTCTRL_BAT_SetRefLow(bLow);
  StablisationDelay();
  
  /* Start current sense amplifier for sensing the input current */
  CURSENSEHW_VIN_Start();  
  /* Start current sense amplifier for sensing the battery current */
  CURSENSEHW_BAT_Start();  
  StablisationDelay();
  
  Bat_Dim_SetPulseWidth(DC_0);
  Bat_Dim_Start();	
  
  /* Start the Hysteretic Controller for the battery current control */
  HYSTCTRL_BAT_Start(); 
}  

//****************************************************************************
//****************************************************************************
// FUNCTION NAME: InitCommUM
//
// DESCRIPTION:
//   Initialise and start I2C
//
//----------------------------------------------------------------------------
//
// ARGUMENTS: none
//
// RETURNS:   none
//****************************************************************************
void InitCommUM()
{
  /* Start EzI2C Module */  
  EzI2Cs_Start();                            // Turn on I2C   
  
  /* Set the ROM Buffer */
  EzI2Cs_SetRomBuffer(DATA_BUFFER, (const BYTE *) E2PROM_START_ADDR);   // Set up ROM buffer
}

//****************************************************************************
//****************************************************************************
// FUNCTION NAME: StablisationDelay
//
// DESCRIPTION:
//   	Add stabilisation delay 
//   
//****************************************************************************
void StablisationDelay()
{
  unsigned int wIndex;
  for(wIndex = 0; wIndex < 50000; wIndex++);			    
}
